home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
CBGRX100.ARJ
/
CURSOR.C
< prev
next >
Wrap
Text File
|
1992-04-10
|
8KB
|
281 lines
/**
** CURSOR.C
**
** Copyright (C) 1992, Csaba Biegl
** 820 Stirrup Dr, Nashville, TN, 37221
** csaba@vuse.vanderbilt.edu
**
** This file is distributed under the terms listed in the document
** "copying.cb", available from the author at the address above.
** A copy of "copying.cb" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.cb".
** You should also have received a copy of the GNU General Public
** License along with this program (it is in the file "copying");
** if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
** Cambridge, MA 02139, USA.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**/
#include "grx.h"
#include "mousex.h"
#include "libgrx.h"
#include "gmalloc.h"
GrCursor *_GrMouseCursor = NULL;
GrCursor *GrBuildCursor(char *bits,int w,int h,int xo,int yo,GrColorTableP ct)
{
GrCursor *c = _GrMalloc(sizeof(GrCursor));
GrContext save,work;
unsigned char *bp;
int workw = (w + w + 15) & ~7;
int workh = (h + h + 7) & ~1;
long csize = GrContextSize(w,h);
long wsize = GrContextSize(workw,workh);
int ww,hh,color,onscreen = FALSE;
char far *vdata;
char far *data;
long addr;
if(c == NULL) return(NULL);
#if !defined(__GNUC__) || (__GNUC__ != 2)
/* something is fishy in GCC 2.0 at this time !! */
/* maybe I will chase it down if I have enough time */
#if (GRXPLANES & 4)
if(_GrNumColors == 16) {
long wsize2 = GrPlaneSize(workw,workh);
vdata = _GrVidAlloc((int)(2 * wsize2));
if(vdata != (char far *)NULL) {
onscreen = TRUE;
wsize = wsize2;
}
}
#endif
#endif
data = _GrFarMalloc((csize + (onscreen ? 0L : wsize)) * 2);
if(data == (char far *)NULL) {
_GrFree(c);
if(onscreen) _GrVidFree(vdata);
return(NULL);
}
c->cr_xcord = c->cr_ycord = 0;
c->cr_xwpos = c->cr_ywpos = 0;
c->cr_xsize = w;
c->cr_ysize = h;
c->cr_xoffs = xo;
c->cr_yoffs = yo;
c->cr_xwork = workw;
c->cr_ywork = workh;
c->cr_displayed = FALSE;
GrSaveContext(&save);
GrCreateContext(w,h,data,&work);
data = (char far *)((char huge *)data + csize);
GrSetContext(&work);
bp = (unsigned char *)bits;
for(hh = 0; hh < h; hh++) {
addr = PIXEL_ADDR(0,hh);
_GrSetPixRow(addr,C_COLOR,w);
for(ww = 0; ww < w; ww++) {
if(*bp++ != 0) _GrSetPixel(addr,0);
addr += PIXEL_SIZE;
}
}
c->cr_andmask = *((GrVidRAM *)&work);
GrCreateContext(w,h,data,&work);
data = (char far *)((char huge *)data + csize);
GrSetContext(&work);
bp = (unsigned char *)bits;
for(hh = 0; hh < h; hh++) {
addr = PIXEL_ADDR(0,hh);
_GrSetPixRow(addr,0,w);
for(ww = 0; ww < w; ww++) {
if((color = *bp++) != 0) {
color--;
if(ct != NULL) color = GR_CTABLE_COLOR(ct,color);
_GrSetPixel(addr,(color & C_COLOR));
}
addr += PIXEL_SIZE;
}
}
c->cr_ormask = *((GrVidRAM *)&work);
if(!onscreen) vdata = data;
GrCreateContext(workw,workh,vdata,&work);
vdata = (char far *)((char huge *)vdata + wsize);
c->cr_work = *((GrVidRAM *)&work);
if(onscreen) {
c->cr_work.gc_onscreen = TRUE;
c->cr_work.gc_planeoffset = 0L;
}
GrCreateContext(workw,workh,vdata,&work);
c->cr_save = *((GrVidRAM *)&work);
if(onscreen) {
c->cr_save.gc_onscreen = TRUE;
c->cr_save.gc_planeoffset = 0L;
}
GrSetContext(&save);
return(c);
}
void GrDestroyCursor(GrCursor *cursor)
{
if(cursor && (cursor != _GrMouseCursor)) {
GrEraseCursor(cursor);
_GrFarFree(cursor->cr_andmask.gc_baseaddr);
if(cursor->cr_work.gc_onscreen)
_GrVidFree(cursor->cr_work.gc_baseaddr);
_GrFree(cursor);
}
}
void GrDisplayCursor(GrCursor *cursor)
{
int xpos,ypos;
int xwrk,ywrk;
int xsiz,ysiz;
if(cursor->cr_displayed) return;
cursor->cr_displayed = TRUE;
xpos = cursor->cr_xcord - cursor->cr_xoffs;
ypos = cursor->cr_ycord - cursor->cr_yoffs;
xsiz = cursor->cr_xwork;
ysiz = cursor->cr_ywork;
xwrk = (xpos - (cursor->cr_xsize >> 1)) & ~7;
ywrk = (ypos - (cursor->cr_ysize >> 1));
if(xwrk < 0) xwrk = 0;
if(ywrk < 0) ywrk = 0;
if(xwrk > (_GrScreenX - xsiz)) xwrk = _GrScreenX - xsiz;
if(ywrk > (_GrScreenY - ysiz)) ywrk = _GrScreenY - ysiz;
cursor->cr_xwpos = xwrk;
cursor->cr_ywpos = ywrk;
_GrPixCopy((GrContext *)&cursor->cr_save,
PIX_ADDR(&cursor->cr_save,0,0),
SCREEN,
PIX_ADDR(SCREEN,xwrk,ywrk),
xsiz,ysiz,
GrWRITE
);
_GrPixCopy((GrContext *)&cursor->cr_work,
PIX_ADDR(&cursor->cr_work,0,0),
(GrContext *)&cursor->cr_save,
PIX_ADDR(&cursor->cr_save,0,0),
xsiz,ysiz,
GrWRITE
);
xpos -= xwrk;
ypos -= ywrk;
xsiz = cursor->cr_xsize;
ysiz = cursor->cr_ysize;
xwrk = ywrk = 0;
if(xpos < 0) { xwrk -= xpos; xsiz += xpos; xpos = 0; }
if(ypos < 0) { ywrk -= ypos; ysiz += ypos; ypos = 0; }
if(xsiz > (cursor->cr_xwork - xpos)) xsiz = cursor->cr_xwork - xpos;
if(ysiz > (cursor->cr_ywork - ypos)) ysiz = cursor->cr_ywork - ypos;
if((xsiz <= 0) || (ysiz <= 0)) return;
_GrPixCopy((GrContext *)&cursor->cr_work,
PIX_ADDR(&cursor->cr_work,xpos,ypos),
(GrContext *)&cursor->cr_andmask,
PIX_ADDR(&cursor->cr_andmask,xwrk,ywrk),
xsiz,ysiz,
GrAND
);
_GrPixCopy((GrContext *)&cursor->cr_work,
PIX_ADDR(&cursor->cr_work,xpos,ypos),
(GrContext *)&cursor->cr_ormask,
PIX_ADDR(&cursor->cr_ormask,xwrk,ywrk),
xsiz,ysiz,
GrOR
);
xpos = cursor->cr_xwpos;
ypos = cursor->cr_ywpos;
_GrPixCopy(SCREEN,
PIX_ADDR(SCREEN,xpos,ypos),
(GrContext *)&cursor->cr_work,
PIX_ADDR(&cursor->cr_work,0,0),
cursor->cr_xwork,cursor->cr_ywork,
GrWRITE
);
}
void GrEraseCursor(GrCursor *cursor)
{
int xpos = cursor->cr_xwpos;
int ypos = cursor->cr_ywpos;
if(cursor->cr_displayed) {
_GrPixCopy(SCREEN,
PIX_ADDR(SCREEN,xpos,ypos),
(GrContext *)&cursor->cr_save,
PIX_ADDR(&cursor->cr_save,0,0),
cursor->cr_xwork,cursor->cr_ywork,
GrWRITE
);
cursor->cr_displayed = FALSE;
}
}
void GrMoveCursor(GrCursor *cursor,int x,int y)
{
int xpos,ypos;
int xsiz,ysiz;
if((cursor->cr_xcord == x) && (cursor->cr_ycord == y)) return;
cursor->cr_xcord = x;
cursor->cr_ycord = y;
if(!cursor->cr_displayed) return;
xpos = x - cursor->cr_xoffs - cursor->cr_xwpos;
ypos = y - cursor->cr_yoffs - cursor->cr_ywpos;
xsiz = cursor->cr_xsize;
ysiz = cursor->cr_ysize;
if((xpos >= 0) && ((xpos + xsiz) <= cursor->cr_xwork) &&
(ypos >= 0) && ((ypos + ysiz) <= cursor->cr_ywork)) {
_GrPixCopy((GrContext *)&cursor->cr_work,
PIX_ADDR(&cursor->cr_work,0,0),
(GrContext *)&cursor->cr_save,
PIX_ADDR(&cursor->cr_save,0,0),
cursor->cr_xwork,cursor->cr_ywork,
GrWRITE
);
_GrPixCopy((GrContext *)&cursor->cr_work,
PIX_ADDR(&cursor->cr_work,xpos,ypos),
(GrContext *)&cursor->cr_andmask,
PIX_ADDR(&cursor->cr_andmask,0,0),
xsiz,ysiz,
GrAND
);
_GrPixCopy((GrContext *)&cursor->cr_work,
PIX_ADDR(&cursor->cr_work,xpos,ypos),
(GrContext *)&cursor->cr_ormask,
PIX_ADDR(&cursor->cr_ormask,0,0),
xsiz,ysiz,
GrOR
);
xpos = cursor->cr_xwpos;
ypos = cursor->cr_ywpos;
_GrPixCopy(SCREEN,
PIX_ADDR(SCREEN,xpos,ypos),
(GrContext *)&cursor->cr_work,
PIX_ADDR(&cursor->cr_work,0,0),
cursor->cr_xwork,cursor->cr_ywork,
GrWRITE
);
return;
}
GrEraseCursor(cursor);
GrDisplayCursor(cursor);
}